package org.codingq92.basic.thread;

import java.util.concurrent.TimeUnit;

/**
 * Synchronized 关键字 <br/>
 * 1.非静态方法 synchronized 锁的对象,也就是方法的调用者(new对象1和new对象2互不影响,各自获取各自的对象锁～) <br/>
 * 2.静态方法 synchronized 锁的是类（new对象1和new对象2都会有影响～） <br/>
 * 3.synchronized块 synchronized(对象) 锁的对象就是括号中的对象～
 *
 * @author: CodingQ92
 * @date: 2025/5/18 22:29
 */
public class CaseSynchronized {
    public static void main(String[] args) {
        noSynchronizedFunc();
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        synchronizedFunc();
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        synchronizedBlock();
    }

    private static void synchronizedBlock() {
//        SynchronizedBlockData blockData = new SynchronizedBlockData();
        for (int i = 0; i < 3; i++) {
            SynchronizedBlockData blockData = new SynchronizedBlockData();
            new Thread(() -> blockData.add()).start();
        }
    }

    /**
     * 非静态方法且方法!!未加!!synchronized关键字<br/>
     * 输出的顺序会是反着的 先 2 后 1
     *
     * @author: CodingQ92
     * @date: 2025/5/18 22:33
     */
    private static void noSynchronizedFunc() {
        NoSynchronizedData noSynchronizedData = new NoSynchronizedData();
        new Thread(() -> noSynchronizedData.add(), "A").start();
        new Thread(() -> noSynchronizedData.diff(), "B").start();
    }

    /**
     * 非静态方法且方法!!加!!synchronized关键字<br/>
     * 输出的顺序会是反着的 先 1 后 2<br/>
     *
     * @author: CodingQ92
     * @date: 2025/5/18 22:43
     */
    private static void synchronizedFunc() {
        SynchronizedData synchronizedData = new SynchronizedData();
        new Thread(() -> synchronizedData.add(), "A").start();
        new Thread(() -> synchronizedData.diff(), "B").start();
    }
}

class NoSynchronizedData {
    public void add() {
        try {
            TimeUnit.SECONDS.sleep(2);
            System.out.println("no sync >>> 1");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void diff() {
        System.out.println("no sync >>> 2");
    }
}

class SynchronizedData {
    public synchronized void add() {
        try {
            TimeUnit.SECONDS.sleep(2);
            System.out.println("sync >>> 1");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public synchronized void diff() {
        System.out.println("sync >>> 2");
    }
}

class SynchronizedBlockData {
    public void add() {
//        synchronized (this) { // 同步代码块this:代表当前的对象 所以new 不同对象就会导致不同的效果 等同于非静态方法的逻辑
        synchronized (SynchronizedBlockData.class) { // 同步代码块SynchronizedBlockData.class:代表当前的class类 所以new 不同对象效果是一样的 等同于静态方法的逻辑
            System.out.println("block >>> beg");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("block >>> end");
        }
    }
}
